home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998…eptember: Technology Seed / September 98 ADC Seed CD.toast / Language Analysis Manager / DarumaDR1Package / Examples / DictionaryAccess / Sources / DictionaryDialog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-29  |  32.1 KB  |  980 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        DictionaryDialog.c
  3.     
  4.     Contains:    A Sample application for dictionary access.
  5.  
  6.      Version:    Technology:    System 8
  7.                  Release:    Daruma Developer Release 1
  8.  
  9.      Copyright:    1998 by Apple Computer, Inc., all rights reserved
  10.  
  11.      Contact:    daruma@apple.com
  12.  
  13. */
  14.  
  15.  
  16. #include <AEDataModel.h>
  17. #include <Appearance.h>
  18. #include <StandardFile.h>
  19. #include <Lists.h>
  20. #include <Resources.h>
  21. #include <NumberFormatting.h>    // for NumToString()
  22. #include "DictionaryAccess.h"
  23. #include "FunctionProto.h"
  24.  
  25. // ========================================================================================
  26. // Prototypes for static functions
  27. // ========================================================================================
  28. static DictionaryDialogPtr CreateDictionaryDialog ( const FSSpec *dictionaryFile );
  29. static void DoDictionaryDialogEvent ( DictionaryDialogPtr dictDialog );
  30. static void DisposeDictionaryDialog( DictionaryDialogPtr dictDialog);
  31. static void FindDictionaryRecord( DictionaryDialogPtr dictDialog);
  32. static void AddDictionaryRecord( DictionaryDialogPtr dictDialog);
  33. static void RemoveDictionaryRecord( DictionaryDialogPtr dictDialog);
  34. static void SelectDictionaryHinshi( DictionaryDialogPtr dictDialog);
  35. static void SelectDictionaryFoundKeyList( DictionaryDialogPtr dictDialog);
  36. static void EraseFoundFieldText( DictionaryDialogPtr dictDialog);
  37. static void EraseFoundListContents( DictionaryDialogPtr dictDialog);
  38. static OSStatus SetUpDictionaryKeyPopup( DictionaryDialogPtr dictDialog);
  39. static void ChangeDictionaryKey( DictionaryDialogPtr dictDialog);
  40. static OSStatus SetupFindMethodPopup( DictionaryDialogPtr dictDialog);
  41. static void ChangeFindMethod( DictionaryDialogPtr dictDialog);
  42. static void CheckReadOnlyDictionary( DictionaryDialogPtr dictDialog);
  43. static pascal Boolean MyModalDialogFilter( DialogPtr dialog, EventRecord *theEvent, DialogItemIndex *itemHit);
  44.  
  45.  
  46. // ========================================================================================
  47. // DoOpenDictionaryFile
  48. // ========================================================================================
  49. void DoOpenDictionaryFile( void )
  50. {
  51.     DictionaryDialogPtr    dictDialog;
  52.     SInt16                numTypes;
  53.     SFTypeList            typeList;
  54.     StandardFileReply    reply;
  55.     
  56.     numTypes = 1;
  57.     typeList[0] = 'dict';
  58.     
  59.     // Select dictionary file
  60.     StandardGetFile( NULL, numTypes, typeList, &reply);
  61.     if ( !reply.sfGood ) return;
  62.     
  63.     // Create dictionary dialog
  64.     dictDialog = CreateDictionaryDialog( &reply.sfFile);
  65.     
  66.     if ( dictDialog != NULL)
  67.     {
  68.         // Handle event
  69.         DoDictionaryDialogEvent( dictDialog);
  70.         
  71.         // Dispose dictionary dialog
  72.         DisposeDictionaryDialog( dictDialog);
  73.     }
  74. }
  75.  
  76.  
  77. // ========================================================================================
  78. // CreateDictionaryDialog
  79. // ========================================================================================
  80. static DictionaryDialogPtr CreateDictionaryDialog ( const FSSpec *dictionaryFile )
  81. {
  82.     OSStatus                err;
  83.     DialogPtr                dialog;
  84.     DictionaryDialogPtr        dictDialog;
  85.     ControlHandle            controlHandle;
  86.     
  87.     //------------------------------------------------------------------------------
  88.     // Create dialog
  89.     //
  90.     dictDialog = (DictionaryDialogPtr)NewPtrClear( sizeof( DictionaryDialogRec));
  91.     require_action( dictDialog, allocDialogInfo_Failure, err = memFullErr;);
  92.     
  93.     dialog = GetNewDialog( kDictionaryDialogResID, dictDialog, (WindowRef)-1L);
  94.     require_action( dialog, getDialog_Failure, err = ResError(););
  95.     
  96.     SetWTitle( dialog, dictionaryFile->name);
  97.     
  98.     dictDialog->dictionaryFile            = *dictionaryFile;
  99.     dictDialog->dictionaryID            = kDCMInvalidObjectID;
  100.     dictDialog->dictionaryRef            = kDCMInvalidObjectRef;
  101.     dictDialog->lastSelectedListIndex    = -1;
  102.  
  103.     //------------------------------------------------------------------------------
  104.     // Check that the dictionary file is already registered
  105.     //
  106.     err = DCMGetDictionaryIDFromFile( dictionaryFile, &dictDialog->dictionaryID);
  107.     if ( err != noErr )
  108.     {
  109.         // Register this dictionary temporary
  110.         err = DCMRegisterDictionaryFile( dictionaryFile,  &dictDialog->dictionaryID);
  111.         nrequire( err, registerDictionary_Failure);
  112.         
  113.         dictDialog->registeredByMe = true;
  114.     }
  115.  
  116.     //------------------------------------------------------------------------------
  117.     // Open dictionary
  118.     //
  119.     err = DCMOpenDictionary( dictDialog->dictionaryID, 0L, NULL, &dictDialog->dictionaryRef);
  120.     nrequire( err, openDictionary_Failure);
  121.  
  122.     //------------------------------------------------------------------------------
  123.     // Setup key popup menu
  124.     //
  125.     err = SetUpDictionaryKeyPopup( dictDialog);
  126.     nrequire( err, setupKeyMenu_Failure);
  127.  
  128.     //------------------------------------------------------------------------------
  129.     // Setup find method popup menu
  130.     //
  131.     err = SetupFindMethodPopup( dictDialog);
  132.     nrequire( err, setupFindMethod_Failure);
  133.     
  134.     //------------------------------------------------------------------------------
  135.     // Check that the dictionary is read only or writable
  136.     //
  137.     CheckReadOnlyDictionary( dictDialog);
  138.     
  139.     //------------------------------------------------------------------------------
  140.     // Set default/cancel button and select edit text item
  141.     //
  142.     SetDialogDefaultItem( dialog, kFindBtnDItemID);
  143.     SetDialogCancelItem( dialog, kDoneBtnDItemID);
  144.     
  145.     GetDialogItemAsControl( dialog, kKeyEditTextDItemID, &controlHandle);
  146.     SetKeyboardFocus( (WindowPtr)dialog, controlHandle, kControlEditTextPart);
  147.  
  148.     ShowWindow( (WindowPtr)dialog);
  149.     
  150.     return dictDialog;
  151.  
  152.     //`````````````````````````````````````````````````````````````````````````````
  153.     // Error handling
  154.     //
  155. setupFindMethod_Failure:
  156. setupKeyMenu_Failure:
  157.     DCMCloseDictionary( dictDialog->dictionaryRef);
  158. openDictionary_Failure:
  159.     if ( dictDialog->registeredByMe)
  160.         DCMUnregisterDictionary( dictDialog->dictionaryID);
  161. registerDictionary_Failure:
  162.     CloseDialog( dialog);
  163. getDialog_Failure:
  164.     DisposePtr( (Ptr)dictDialog);
  165. allocDialogInfo_Failure:
  166.     return NULL;
  167. }
  168.  
  169.  
  170. // ========================================================================================
  171. // DoDictionaryDialogEvent
  172. // ========================================================================================
  173. static void DoDictionaryDialogEvent ( DictionaryDialogPtr dictDialog )
  174. {
  175.     SInt16                itemHit = 0;
  176.     ModalFilterUPP        filterUPP;
  177.     
  178.     filterUPP = NewModalFilterProc( MyModalDialogFilter);
  179.     
  180.     do
  181.     {
  182.         ModalDialog( filterUPP, &itemHit);
  183.         
  184.         switch ( itemHit)
  185.         {
  186.         case kFindBtnDItemID:
  187.             FindDictionaryRecord( dictDialog);
  188.             break;
  189.             
  190.         case kAddBtnDItemID:
  191.             AddDictionaryRecord( dictDialog);
  192.             break;
  193.             
  194.         case kRemoveBtnDItemID:
  195.             RemoveDictionaryRecord( dictDialog);
  196.             break;
  197.             
  198.         case kKeyPopupDItemID:
  199.             ChangeDictionaryKey( dictDialog);
  200.             break;
  201.             
  202.         case kFindMethodPopupDItemID:
  203.             ChangeFindMethod( dictDialog);
  204.             break;
  205.         
  206.         case kHinshiPopupDItemID:
  207.             SelectDictionaryHinshi( dictDialog);
  208.             break;
  209.             
  210.         case kFoundKeyListDItemID:
  211.             SelectDictionaryFoundKeyList( dictDialog);
  212.             break;
  213.             
  214.         default: break;
  215.         }
  216.     }
  217.     while ( itemHit != kDoneBtnDItemID);
  218.     
  219.     DisposeRoutineDescriptor( filterUPP);
  220. }
  221.  
  222.  
  223. // ========================================================================================
  224. // DisposeDictionaryDialog
  225. // ========================================================================================
  226. static void DisposeDictionaryDialog( DictionaryDialogPtr dictDialog)
  227. {
  228.     //------------------------------------------------------------------------------
  229.     // Close and unregister dictionary (if needed)
  230.     //
  231.     DCMCloseDictionary( dictDialog->dictionaryRef);
  232.     
  233.     if ( dictDialog->registeredByMe)
  234.         DCMUnregisterDictionary( dictDialog->dictionaryID);
  235.  
  236.     //------------------------------------------------------------------------------
  237.     // Free memory
  238.     //
  239.     if ( dictDialog->foundUniqueIDs != NULL )
  240.         DisposePtr( (Ptr)dictDialog->foundUniqueIDs);
  241.     
  242.     CloseDialog( (DialogPtr)dictDialog);
  243.     DisposePtr( (Ptr)dictDialog);
  244. }
  245.  
  246.  
  247. // ========================================================================================
  248. // FindDictionaryRecord
  249. // ========================================================================================
  250. static void FindDictionaryRecord( DictionaryDialogPtr dictDialog)
  251. {
  252.     OSStatus                err;
  253.     ListHandle                listHandle;
  254.     ControlHandle            controlHandle;
  255.     Str255                    string;
  256.     DCMFoundRecordIterator    recordIterator;
  257.     ByteCount                actualSize;
  258.     ItemCount                foundRecordCount, i;
  259.     Cell                    listCell = { 0, 0};
  260.     
  261.     //------------------------------------------------------------------------------
  262.     // Clean up display
  263.     //
  264.     EraseFoundListContents( dictDialog);
  265.     EraseFoundFieldText( dictDialog);
  266.  
  267.     //------------------------------------------------------------------------------
  268.     // Get list handle
  269.     //
  270.     err = GetDialogItemAsControl( (DialogPtr)dictDialog, kFoundKeyListDItemID, &controlHandle);
  271.     nrequire( err, getControl_Failure);
  272.     
  273.     listHandle = GetListHandleFromControl( controlHandle);
  274.     require( listHandle, getListHandle_Failure);
  275.     
  276.     //------------------------------------------------------------------------------
  277.     // Get key string
  278.     //
  279.     GetDialogEditTextItemString( (DialogPtr)dictDialog, kKeyEditTextDItemID, string);
  280.     
  281.     //------------------------------------------------------------------------------
  282.     // Search dictionary
  283.     // In this sample, finds records without any pre-fetched data. So, all data should
  284.     // be fetched later by using DCMGetFieldData(). That's a suitable way for this sample.
  285.     // In general, however, method using pre-fetched data is faster than that using DCMGetFieldData().
  286.     //
  287.     err = DCMFindRecords( dictDialog->dictionaryRef, dictDialog->currentKeyField, string[0],
  288.                           &string[1], dictDialog->currentFindMethod, 0, NULL, 0, 0, &recordIterator);
  289.     if ( err != dcmNoRecordErr)
  290.         nrequire( err, findRecord_Failure);
  291.     
  292.     //------------------------------------------------------------------------------
  293.     // Create uniqueID array for saving uniqueID of each found record
  294.     //
  295.     foundRecordCount = DCMCountRecordIterator( recordIterator);
  296.  
  297.     if ( dictDialog->foundUniqueIDs != NULL)
  298.         DisposePtr( (Ptr)dictDialog->foundUniqueIDs);
  299.     
  300.     dictDialog->foundUniqueIDs = (DCMUniqueID *)NewPtrClear( sizeof( DCMUniqueID) * foundRecordCount);
  301.     require_action( dictDialog->foundUniqueIDs, createUniqueIDList_Failure, err = memFullErr;);
  302.     
  303.     //------------------------------------------------------------------------------
  304.     // Add found record's keys into list
  305.     //
  306.     LSetDrawingMode( false, listHandle);
  307.     for ( i = 0; i < foundRecordCount; i++ )
  308.     {
  309.         err = DCMIterateFoundRecord( recordIterator, sizeof( string) - 1, &actualSize,
  310.                                      &string[1], &dictDialog->foundUniqueIDs[i], NULL);
  311.         nrequire( err, iterateRecord_Failure);
  312.         string[0] = actualSize;
  313.         
  314.         listCell.v = LAddRow( 1, i, listHandle);
  315.         LSetCell( &string[1], string[0], listCell, listHandle);
  316.     }
  317.     LSetDrawingMode( true, listHandle);
  318.     DrawOneControl( controlHandle);
  319.     
  320.     //------------------------------------------------------------------------------
  321.     // Dispose iterator object (don't forget it!)
  322.     //
  323.     DCMDisposeRecordIterator( recordIterator);
  324.     
  325.     return;
  326.     
  327.     //`````````````````````````````````````````````````````````````````````````````
  328.     // Error handling
  329.     //
  330. iterateRecord_Failure:
  331. createUniqueIDList_Failure:
  332.     DCMDisposeRecordIterator( recordIterator);
  333. findRecord_Failure:
  334. getListHandle_Failure:
  335. getControl_Failure:
  336.     return;
  337. }
  338.  
  339.  
  340. // ========================================================================================
  341. // AddDictionaryRecord
  342. // ========================================================================================
  343. static void AddDictionaryRecord( DictionaryDialogPtr dictDialog)
  344. {
  345.     OSStatus                err;
  346.     AERecord                recordData    = { typeNull, NULL};
  347.     DCMFieldTag                dataField;
  348.     Str255                    keyString, dataString, tempString;
  349.     long                    tempNum;
  350.     HomographWeight            wordWeight;
  351.     JapanesePartOfSpeech    hinshiCode;
  352.     DCMUniqueID                newUniqueID;
  353.  
  354.     //------------------------------------------------------------------------------
  355.     // Prepare data
  356.     //
  357.     GetDialogEditTextItemString( (DialogPtr)dictDialog, kKeyEditTextDItemID, keyString);
  358.     GetDialogEditTextItemString( (DialogPtr)dictDialog, kDataEditTextDItemID, dataString);
  359.     
  360.     GetDialogEditTextItemString( (DialogPtr)dictDialog, kWeightEditTextDItemID, tempString);
  361.     StringToNum( tempString, &tempNum);
  362.     wordWeight = tempNum;
  363.     
  364.     GetDialogStaticTextItemString( (DialogPtr)dictDialog, kHinshiStatTextDItemID, tempString);
  365.     {
  366.         //
  367.         // Convert hinshi name to hinshi code using coercion.
  368.         //
  369.         AEDesc    hinshiDesc = { typeNull, NULL};
  370.         
  371.         err = AECoercePtr( typeChar, &tempString[1], tempString[0], kDCMJapaneseHinshiType, &hinshiDesc);
  372.         if ( err == noErr)
  373.             BlockMoveData( *hinshiDesc.dataHandle, &hinshiCode, sizeof(hinshiCode));
  374.         else
  375.             hinshiCode = 0;
  376.         
  377.         AEDisposeDesc( &hinshiDesc);
  378.     }
  379.  
  380.     //------------------------------------------------------------------------------
  381.     // Create a data record for adding new entry to the dictionary
  382.     //
  383.     err = AECreateList( NULL, 0L, true, &recordData);
  384.     nrequire( err, createRecord_Failure);
  385.     
  386.     // Set data string
  387.     dataField = ( dictDialog->currentKeyField == kDCMJapaneseYomiTag ? kDCMJapaneseHyokiTag : kDCMJapaneseYomiTag);
  388.     err = AEPutKeyPtr( &recordData, dataField, typeChar, &dataString[1], dataString[0]);
  389.     nrequire( err, addDataString_Failure);
  390.  
  391.     // Set hinshi
  392.     err = AEPutKeyPtr( &recordData, kDCMJapaneseHinshiTag, kDCMJapaneseHinshiType, &hinshiCode, sizeof(hinshiCode));
  393.     nrequire( err, addHinshi_Failure);
  394.     
  395.     // Set word weight
  396.     err = AEPutKeyPtr( &recordData, kDCMJapaneseWeightTag, kDCMJapaneseWeightType, &wordWeight, sizeof(wordWeight));
  397.     nrequire( err, addWordWeight_Failure);
  398.     
  399.     //------------------------------------------------------------------------------
  400.     // At first, get write access of the dictionary
  401.     //
  402.     err = DCMGetDictionaryWriteAccess( dictDialog->dictionaryRef, 0L);
  403.     nrequire( err, getWriteAccess_Failure);
  404.  
  405.     //------------------------------------------------------------------------------
  406.     // Add new record to the dictionary
  407.     //
  408.     err = DCMAddRecord( dictDialog->dictionaryRef, dictDialog->currentKeyField, keyString[0],
  409.                         &keyString[1], false, &recordData, &newUniqueID);
  410.     // dcmDupRecordErr is NOT an error, ignore it
  411.     if ( err != dcmDupRecordErr)
  412.         nrequire( err, addRecord_Failure);
  413.     
  414.     //------------------------------------------------------------------------------
  415.     // Release write access as soon as possible
  416.     //
  417.     DCMReleaseDictionaryWriteAccess( dictDialog->dictionaryRef, true);
  418.  
  419.     //------------------------------------------------------------------------------
  420.     // Clean up
  421.     //
  422.     AEDisposeDesc( &recordData);
  423.     
  424.     return;
  425.  
  426.     //`````````````````````````````````````````````````````````````````````````````
  427.     // Error handling
  428.     //
  429. addRecord_Failure:
  430.     DCMReleaseDictionaryWriteAccess( dictDialog->dictionaryRef, true);
  431. getWriteAccess_Failure:
  432. addWordWeight_Failure:
  433. addHinshi_Failure:
  434. addDataString_Failure:
  435.     AEDisposeDesc( &recordData);
  436. createRecord_Failure:
  437.     return;
  438. }
  439.  
  440.  
  441. // ========================================================================================
  442. // RemoveDictionaryRecord
  443. // ========================================================================================
  444. static void RemoveDictionaryRecord( DictionaryDialogPtr dictDialog)
  445. {
  446.     OSStatus        err;
  447.     Str255            keyString;
  448.     
  449.     //------------------------------------------------------------------------------
  450.     // Get target key string
  451.     //
  452.     GetDialogEditTextItemString( (DialogPtr)dictDialog, kKeyEditTextDItemID, keyString);
  453.  
  454.     //------------------------------------------------------------------------------
  455.     // Get write access of the target dictionary
  456.     //
  457.     err = DCMGetDictionaryWriteAccess( dictDialog->dictionaryRef, 0L);
  458.     nrequire( err, getWriteAccess_Failure);
  459.  
  460.     //------------------------------------------------------------------------------
  461.     // Delete a record from dictionary
  462.     //
  463.     err = DCMDeleteRecord( dictDialog->dictionaryRef, dictDialog->currentKeyField,
  464.                            keyString[0], &keyString[1], dictDialog->lastSelectedUniqueID);
  465.     nrequire( err, deleteRecord_Failure);
  466.     
  467.     //------------------------------------------------------------------------------
  468.     // Release write access of target dictionary
  469.     //
  470.     DCMReleaseDictionaryWriteAccess( dictDialog->dictionaryRef, true);
  471.     
  472.     //------------------------------------------------------------------------------
  473.     // Update display
  474.     //
  475.     SetDialogEditTextItemString( (DialogPtr)dictDialog, kKeyEditTextDItemID, "\p");
  476.     EraseFoundFieldText( dictDialog);
  477.     EraseFoundListContents( dictDialog);
  478.     
  479.     return;
  480.     
  481.     //`````````````````````````````````````````````````````````````````````````````
  482.     // Error handling
  483.     //
  484. deleteRecord_Failure:
  485.     DCMReleaseDictionaryWriteAccess( dictDialog->dictionaryRef, false);
  486. getWriteAccess_Failure:
  487.     return;
  488. }
  489.  
  490.  
  491. // ========================================================================================
  492. // SelectDictionaryHinshi
  493. // ========================================================================================
  494. static void SelectDictionaryHinshi( DictionaryDialogPtr dictDialog)
  495. {
  496.     OSStatus        err;
  497.     ControlHandle    popupControl;
  498.     SInt16            selectedItem;
  499.     Str255            hinshiName;
  500.     MenuHandle        hinshiMenu = GetMenuHandle( kHinshiPopupMenuID);
  501.     
  502.     err = GetDialogItemAsControl( (DialogPtr)dictDialog, kHinshiPopupDItemID, &popupControl);
  503.     nrequire( err, getPopupControl_Failure);
  504.  
  505.     selectedItem = GetControlValue( popupControl);
  506.     GetMenuItemText( hinshiMenu, selectedItem, hinshiName);
  507.     
  508.     SetDialogStaticTextItemString( (DialogPtr)dictDialog, kHinshiStatTextDItemID, hinshiName);
  509.  
  510.     return;
  511.     
  512.     //`````````````````````````````````````````````````````````````````````````````
  513.     // Error handling
  514.     //
  515. getPopupControl_Failure:
  516.     return;
  517. }
  518.  
  519.  
  520. // ========================================================================================
  521. // SelectDictionaryFoundKeyList
  522. // ========================================================================================
  523. static void SelectDictionaryFoundKeyList( DictionaryDialogPtr dictDialog)
  524. {
  525.     OSStatus                err;
  526.     ListHandle                listHandle;
  527.     ControlHandle            controlHandle;
  528.     Cell                    listCell = { 0, 0};
  529.     Str255                    keyString, dataString;
  530.     Str31                    hinshiString;
  531.     Str15                    weightString;
  532.     AEDesc                    dataList = { typeNull, NULL};
  533.     DescType                actualType;
  534.     Size                    actualSize;
  535.     HomographWeight            wordWeight;
  536.     JapanesePartOfSpeech    hinshiCode;
  537.     
  538.     //------------------------------------------------------------------------------
  539.     // Get list handle
  540.     //
  541.     err = GetDialogItemAsControl( (DialogPtr)dictDialog, kFoundKeyListDItemID, &controlHandle);
  542.     nrequire( err, getControl_Failure);
  543.     
  544.     listHandle = GetListHandleFromControl( controlHandle);
  545.     require( listHandle, getListHandle_Failure);
  546.     
  547.     //------------------------------------------------------------------------------
  548.     // Get the selected cell
  549.     //
  550.     if ( !LGetSelect( true, &listCell, listHandle) )
  551.         listCell.v = -1;
  552.  
  553.     if ( dictDialog->lastSelectedListIndex == listCell.v)    // selected cell is not changed
  554.         return;
  555.     else
  556.         dictDialog->lastSelectedListIndex = listCell.v;
  557.     
  558.     //------------------------------------------------------------------------------
  559.     // Get dictionary data of the selected record
  560.     //
  561.     if ( dictDialog->lastSelectedListIndex != -1 )    // there is selected item
  562.     {
  563.         ItemCount    neededDataNum = 3;
  564.         DCMFieldTag    neededDataTags[3] = { '????', kDCMJapaneseWeightTag, kDCMJapaneseHinshiTag};
  565.         SInt16        cellDataLen;
  566.         
  567.         cellDataLen = sizeof( keyString) - 1;    // This line is easy to forget !
  568.         LGetCell( &keyString[1], &cellDataLen, listCell, listHandle);
  569.         keyString[0] = cellDataLen;
  570.         
  571.         // Get yomi or hyouki, which is not set to the find key
  572.         neededDataTags[0] = ( dictDialog->currentKeyField == kDCMJapaneseYomiTag ? kDCMJapaneseHyokiTag : kDCMJapaneseYomiTag);
  573.         
  574.         // Get dictionary field data of the specified record
  575.         err = DCMGetFieldData( dictDialog->dictionaryRef, dictDialog->currentKeyField,
  576.                                cellDataLen, &keyString[1], dictDialog->foundUniqueIDs[listCell.v],
  577.                                neededDataNum, neededDataTags, &dataList);
  578.         nrequire( err, getFieldData_Failure);
  579.         
  580.         // Retrieve yomi or hyouki string
  581.         err = AEGetKeyPtr( &dataList, neededDataTags[0], typeChar,
  582.                            &actualType, &dataString[1], sizeof(dataString) - 1, &actualSize);
  583.         nrequire( err, getDataString_Failure);
  584.         dataString[0] = actualSize;
  585.         
  586.         // Retrieve word weight and convert it to string
  587.         err = AEGetKeyPtr( &dataList, neededDataTags[1], kDCMJapaneseWeightType,
  588.                            &actualType, &wordWeight, sizeof(wordWeight), &actualSize);
  589.         nrequire( err, getWordWeight_Failure);
  590.         NumToString( wordWeight, weightString);
  591.  
  592.         // Retrieve hinshi code
  593.         err = AEGetKeyPtr( &dataList, neededDataTags[2], kDCMJapaneseHinshiType,
  594.                            &actualType, &hinshiCode, sizeof(hinshiCode), &actualSize);
  595.         nrequire( err, getHinshiCode_Failure);
  596.                 
  597.         // You can convert kDCMJapaneseHinshiType to typeChar by coercing data type.
  598.         // It means that you can get the hinshi name from hinshi code.
  599.         // Note that you cannot get hinshi name directly from AEDesc.
  600.         {
  601.             AEDesc    hinshiDesc = { typeNull, NULL};
  602.             
  603.             err = AECoercePtr( kDCMJapaneseHinshiType, &hinshiCode, sizeof(hinshiCode),
  604.                                typeChar, &hinshiDesc);
  605.             nrequire( err, convertHinshiCode_Failure);
  606.             
  607.             actualSize = GetHandleSize( hinshiDesc.dataHandle);
  608.             BlockMoveData( *hinshiDesc.dataHandle, &hinshiString[1], actualSize);
  609.             hinshiString[0] = actualSize;
  610.             AEDisposeDesc( &hinshiDesc);
  611.         }
  612.         
  613.         // Save uniqueID of the selected record
  614.         dictDialog->lastSelectedUniqueID = dictDialog->foundUniqueIDs[listCell.v];
  615.  
  616.         AEDisposeDesc( &dataList);    // Don't forget it
  617.     }
  618.     else    // no list item is selected
  619.     {
  620.         keyString[0] = 0;
  621.         dataString[0] = 0;
  622.         hinshiString[0] = 0;
  623.         weightString[0] = 0;
  624.     }
  625.     
  626.     //------------------------------------------------------------------------------
  627.     // Set retrieved strings to dialog field
  628.     //
  629.     SetDialogEditTextItemString( (DialogPtr)dictDialog, kKeyEditTextDItemID, keyString);
  630.     SetDialogEditTextItemString( (DialogPtr)dictDialog, kDataEditTextDItemID, dataString);
  631.     SetDialogEditTextItemString( (DialogPtr)dictDialog, kWeightEditTextDItemID, weightString);
  632.     SetDialogStaticTextItemString( (DialogPtr)dictDialog, kHinshiStatTextDItemID, hinshiString);
  633.  
  634.     return;
  635.     
  636.     //`````````````````````````````````````````````````````````````````````````````
  637.     // Error handling
  638.     //
  639. convertHinshiCode_Failure:
  640. getHinshiCode_Failure:
  641. getWordWeight_Failure:
  642. getDataString_Failure:
  643.     AEDisposeDesc( &dataList);
  644. getFieldData_Failure:
  645. getListHandle_Failure:
  646. getControl_Failure:
  647.     return;
  648. }
  649.  
  650.  
  651. // ========================================================================================
  652. // EraseFoundFieldText
  653. // ========================================================================================
  654. static void EraseFoundFieldText( DictionaryDialogPtr dictDialog)
  655. {
  656.     SetDialogEditTextItemString( (DialogPtr)dictDialog, kDataEditTextDItemID, "\p");
  657.     SetDialogEditTextItemString( (DialogPtr)dictDialog, kWeightEditTextDItemID, "\p");
  658.     SetDialogStaticTextItemString( (DialogPtr)dictDialog, kHinshiStatTextDItemID, "\p");
  659. }
  660.  
  661.  
  662. // ========================================================================================
  663. // EraseFoundListContents
  664. // ========================================================================================
  665. static void EraseFoundListContents( DictionaryDialogPtr dictDialog)
  666. {
  667.     OSStatus                err;
  668.     ListHandle                listHandle;
  669.     ControlHandle            controlHandle;
  670.     
  671.     //------------------------------------------------------------------------------
  672.     // Get list handle
  673.     //
  674.     err = GetDialogItemAsControl( (DialogPtr)dictDialog, kFoundKeyListDItemID, &controlHandle);
  675.     
  676.     if ( err == noErr )
  677.     {
  678.         listHandle = GetListHandleFromControl( controlHandle);
  679.         
  680.         if ( listHandle != NULL )
  681.         {
  682.             // Delete list contents
  683.             LDelRow( 0, 0, listHandle);
  684.             dictDialog->lastSelectedListIndex = -1;
  685.             LSetDrawingMode( true, listHandle);
  686.             DrawOneControl( controlHandle);
  687.         }
  688.     }
  689. }
  690.  
  691.  
  692. // ========================================================================================
  693. // SetUpDictionaryKeyPopup
  694. // ========================================================================================
  695. static OSStatus SetUpDictionaryKeyPopup( DictionaryDialogPtr dictDialog)
  696. {
  697.     OSStatus            err;
  698.     AERecord            fieldInfo = { typeNull, NULL};
  699.     UInt16                i, keyCount;
  700.     DCMFieldTag            fieldTags[2] = { kDCMJapaneseYomiTag, kDCMJapaneseHyokiTag};
  701.     DCMFieldAttributes    attribute;
  702.     Str255                fieldName;
  703.     ControlHandle        popupControl;
  704.     MenuHandle            keyMenuHandle = GetMenuHandle( kKeyPopupMenuID);
  705.     
  706.     //------------------------------------------------------------------------------
  707.     // Remove old menu items
  708.     //
  709.     while ( CountMItems( keyMenuHandle) > 0)
  710.         DeleteMenuItem( keyMenuHandle, 1);
  711.  
  712.     //------------------------------------------------------------------------------
  713.     // Get yomi and hyouki field information
  714.     //
  715.     for ( keyCount = 0, i = 0; i < 2; i++ )
  716.     {
  717.         err = DCMGetDictionaryFieldInfo( dictDialog->dictionaryID, fieldTags[i], &fieldInfo);
  718.         nrequire( err, getFieldInfo_Failure);
  719.  
  720.         err = DCMGetFieldAttributes( &fieldInfo, &attribute);
  721.         nrequire( err, getFieldAttr_Failure);
  722.         
  723.         if ( attribute & kDCMIndexedFieldMask)        // indexed field
  724.         {
  725.             err = DCMGetFieldName( &fieldInfo, fieldName);
  726.             nrequire( err, getFieldName_Failure);
  727.             
  728.             AppendMenu( keyMenuHandle, "\pDummy");
  729.             SetMenuItemText( keyMenuHandle, keyCount + 1, fieldName);
  730.  
  731.             dictDialog->keyFields[keyCount] = fieldTags[i];
  732.             keyCount++;
  733.         }
  734.         AEDisposeDesc( &fieldInfo);
  735.     }
  736.     
  737.     //------------------------------------------------------------------------------
  738.     // Setup initial setting
  739.     //
  740.     err = GetDialogItemAsControl( (DialogPtr)dictDialog, kKeyPopupDItemID, &popupControl);
  741.     nrequire( err, getPopupControl_Failure);
  742.     
  743.     SetControlMaximum( popupControl, keyCount);
  744.     SetControlValue( popupControl, 1);
  745.     ChangeDictionaryKey( dictDialog);
  746.     
  747.     return noErr;
  748.  
  749.     //`````````````````````````````````````````````````````````````````````````````
  750.     // Error handling
  751.     //
  752. getPopupControl_Failure:
  753. getFieldName_Failure:
  754. getFieldAttr_Failure:
  755. getFieldInfo_Failure:
  756.     AEDisposeDesc( &fieldInfo);
  757.     return err;
  758. }
  759.  
  760.  
  761. // ========================================================================================
  762. // ChangeDictionaryKey
  763. // ========================================================================================
  764. static void ChangeDictionaryKey( DictionaryDialogPtr dictDialog)
  765. {
  766.     OSStatus            err;
  767.     ControlHandle        popupControl;
  768.     SInt16                index;
  769.     
  770.     err = GetDialogItemAsControl( (DialogPtr)dictDialog, kKeyPopupDItemID, &popupControl);
  771.     nrequire( err, getPopupControl_failure);
  772.     
  773.     index = GetControlValue( popupControl);
  774.     
  775.     if ( dictDialog->currentKeyField == dictDialog->keyFields[index - 1])    // not changed
  776.         return;
  777.     
  778.     dictDialog->currentKeyField = dictDialog->keyFields[index - 1];
  779.     
  780.     //------------------------------------------------------------------------------
  781.     // Change dialog's text field label
  782.     //
  783.     if ( dictDialog->currentKeyField == kDCMJapaneseYomiTag )
  784.     {
  785.         HideDialogItem( (DialogPtr)dictDialog, kYomiTitleStatTextDItemID);
  786.         ShowDialogItem( (DialogPtr)dictDialog, kHyoukiTitleStatTextDItemID);
  787.     }
  788.     else
  789.     {
  790.         HideDialogItem( (DialogPtr)dictDialog, kHyoukiTitleStatTextDItemID);
  791.         ShowDialogItem( (DialogPtr)dictDialog, kYomiTitleStatTextDItemID);
  792.     }
  793.     
  794.     return;
  795.  
  796.     //`````````````````````````````````````````````````````````````````````````````
  797.     // Error handling
  798.     //
  799. getPopupControl_failure:
  800.     return;
  801. }
  802.  
  803.  
  804. // ========================================================================================
  805. // SetupFindMethodPopup
  806. // ========================================================================================
  807. static OSStatus SetupFindMethodPopup( DictionaryDialogPtr dictDialog)
  808. {
  809.     OSStatus            err;
  810.     AERecord            fieldInfo = { typeNull, NULL};
  811.     UInt32                i, findMethodCount;
  812.     Str31                resourceName;
  813.     StringHandle        findMethodNameHandle;
  814.     ControlHandle        popupControl;
  815.     MenuHandle            findMethodMenuHandle = GetMenuHandle( kFindMethodPopupMenuID);
  816.     
  817.     //------------------------------------------------------------------------------
  818.     // Remove old menu items
  819.     //
  820.     while ( CountMItems( findMethodMenuHandle) > 0)
  821.         DeleteMenuItem( findMethodMenuHandle, 1);
  822.  
  823.     //------------------------------------------------------------------------------
  824.     // Get key field information
  825.     //
  826.     err = DCMGetDictionaryFieldInfo( dictDialog->dictionaryID, dictDialog->currentKeyField, &fieldInfo);
  827.     nrequire( err, getFieldInfo_Failure);
  828.     
  829.     err = DCMGetFieldFindMethods( &fieldInfo, dictDialog->findMethods, 5, &findMethodCount);
  830.     nrequire( err, getFindMethod_Failure);
  831.     
  832.     //------------------------------------------------------------------------------
  833.     // Add find method name to the popup menu
  834.     //
  835.     for ( i = 0; i < findMethodCount; i++ )
  836.     {
  837.         // Convert DCMFindMethod to pascal string
  838.         BlockMoveData( &dictDialog->findMethods[i], &resourceName[1], sizeof( DCMFindMethod));
  839.         resourceName[0] = sizeof( DCMFindMethod);
  840.         
  841.         // Get find method name from resource
  842.         findMethodNameHandle = (StringHandle)Get1NamedResource( 'STR ', resourceName);
  843.         if ( findMethodNameHandle == NULL)
  844.             findMethodNameHandle = (StringHandle)Get1Resource( 'STR ', 200);
  845.         HLock( (Handle)findMethodNameHandle);
  846.         
  847.         AppendMenu( findMethodMenuHandle, "\pDummy");
  848.         SetMenuItemText( findMethodMenuHandle, i + 1, *findMethodNameHandle);
  849.         HUnlock( (Handle)findMethodNameHandle);
  850.         ReleaseResource( (Handle)findMethodNameHandle);
  851.     }
  852.     
  853.     //------------------------------------------------------------------------------
  854.     // Setup initial setting
  855.     //
  856.     err = GetDialogItemAsControl( (DialogPtr)dictDialog, kFindMethodPopupDItemID, &popupControl);
  857.     nrequire( err, getPopupControl_Failure);
  858.     
  859.     SetControlMaximum( popupControl, findMethodCount);
  860.     SetControlValue( popupControl, 1);
  861.     ChangeFindMethod( dictDialog);
  862.     
  863.     return noErr;
  864.  
  865.     //`````````````````````````````````````````````````````````````````````````````
  866.     // Error handling
  867.     //
  868. getPopupControl_Failure:
  869. getFindMethod_Failure:
  870. getFieldInfo_Failure:
  871.     return err;
  872. }
  873.  
  874.  
  875. // ========================================================================================
  876. // ChangeFindMethod
  877. // ========================================================================================
  878. static void ChangeFindMethod( DictionaryDialogPtr dictDialog)
  879. {
  880.     OSStatus            err;
  881.     ControlHandle        popupControl;
  882.     SInt16                index;
  883.     
  884.     err = GetDialogItemAsControl( (DialogPtr)dictDialog, kFindMethodPopupDItemID, &popupControl);
  885.     nrequire( err, getPopupControl_Failure);
  886.     
  887.     index = GetControlValue( popupControl);
  888.  
  889.     dictDialog->currentFindMethod = dictDialog->findMethods[index - 1];
  890.  
  891.     return;
  892.     
  893.     //`````````````````````````````````````````````````````````````````````````````
  894.     // Error handling
  895.     //
  896. getPopupControl_Failure:
  897.     return;
  898. }
  899.  
  900.  
  901. // ========================================================================================
  902. // CheckReadOnlyDictionary
  903. // ========================================================================================
  904. static void CheckReadOnlyDictionary( DictionaryDialogPtr dictDialog)
  905. {
  906.     OSStatus            err;
  907.     SInt16                permission;
  908.     ByteCount            actualSize;
  909.     ControlHandle        controlHandle;
  910.     
  911.     //------------------------------------------------------------------------------
  912.     // Get permission property of the dictionary
  913.     //
  914.     err = DCMGetDictionaryProperty( dictDialog->dictionaryID, pDCMPermission,
  915.                                     sizeof( permission), &actualSize, &permission);
  916.     nrequire( err, getPermProperty_Failure);
  917.     
  918.     //------------------------------------------------------------------------------
  919.     // Disable add/remove button if the dictionary is read only
  920.     //
  921.     if ( permission != kDCMReadWriteDictionary)
  922.     {
  923.         err = GetDialogItemAsControl( (DialogPtr)dictDialog, kAddBtnDItemID, &controlHandle);
  924.         if ( err == noErr)
  925.             DeactivateControl( controlHandle);
  926.         
  927.         err = GetDialogItemAsControl( (DialogPtr)dictDialog, kRemoveBtnDItemID, &controlHandle);
  928.         if ( err == noErr)
  929.             DeactivateControl( controlHandle);
  930.     }
  931.  
  932.     return;
  933.     
  934.     //`````````````````````````````````````````````````````````````````````````````
  935.     // Error handling
  936.     //
  937. getPermProperty_Failure:
  938.     return;
  939. }
  940.  
  941.  
  942. // ========================================================================================
  943. // MyModalDialogFilter
  944. // ========================================================================================
  945. static pascal Boolean MyModalDialogFilter( DialogPtr dialog, EventRecord *theEvent, DialogItemIndex *itemHit)
  946. {
  947.     Boolean eventProcessed = false;
  948.     
  949.     //------------------------------------------------------------------------------
  950.     // Handle return/enter key
  951.     //
  952.     if ( theEvent->what == keyDown || theEvent->what == autoKey )
  953.     {
  954.         UInt8 charCode = theEvent->message & charCodeMask;
  955.         
  956.         if ( charCode == kEnterCharCode || charCode == kReturnCharCode)
  957.         {
  958.             *itemHit = kFindBtnDItemID;
  959.             HiliteButtonDialogItem( dialog, kFindBtnDItemID);
  960.             eventProcessed = true;
  961.         }
  962.     }
  963.  
  964.     //------------------------------------------------------------------------------
  965.     // Transfer un-handled event to the default filter
  966.     //
  967.     if ( !eventProcessed )
  968.         eventProcessed = StdFilterProc( dialog, theEvent, itemHit);
  969.     
  970.     return eventProcessed;
  971. }
  972.  
  973.  
  974.  
  975.  
  976.  
  977.  
  978.  
  979.  
  980.